﻿using System;
using System.Collections.Generic;

using BizElements.Core.ProviderComponents;

namespace BizElements.Core.SqlServer
{
    sealed class SqlServer2005ComponentProvider : IDbmsComponentProvider
    {
        private static readonly Dictionary<Type, object> Components = CreateComponents();

        private static Dictionary<Type, object> CreateComponents()
        {
            Dictionary<Type, object> components = new Dictionary<Type, object>();

            // All implementations are stateless, ie. have no fields, and are thread safe.
            // Single instances serve all threads and clients.
            components[typeof(IDbCommandBuilder)] = new SqlServerCommandBuilder();
            components[typeof(IDataAdapterBuilder)] = new SqlServerDataAdapterBuilder();
            components[typeof(IParameterRenderer)] = new SqlServerParameterRenderer();
            components[typeof(IFunctionRenderer)] = new GenericFunctionRenderer();
            components[typeof(IAggregateFunctionRenderer)] = new GenericAggregateFunctionRenderer();
            components[typeof(IColumnRenderer)] = new SqlServerColumnRenderer();
            components[typeof(ITableRenderer)] = new SqlServerTableRenderer();
            if (Settings.ContainsPredicateEnabled)
                components[typeof(IContainsPredicateRenderer)] = new SqlServerContainsPredicateRenderer();
            else
                components[typeof(IContainsPredicateRenderer)] = new ContainsAsLikePredicateRenderer();

            components[typeof(ILikePredicateRenderer)] = new GenericLikeRenderer();
            components[typeof(IFromClauseRenderer)] = new GenericFromClauseRenderer();
            components[typeof(IInserter)] = new SqlServerInserter();
            components[typeof(ISelectRenderer)] = new SqlServerSelectRenderer();
            components[typeof(IUpdater)] = new SqlServerUpdater();
            components[typeof(IDeleteRenderer)] = new GenericDeleteRenderer();
            components[typeof(IHierarchicalQueryExecutor)] = new SqlServerRecursiveCteExecutor();
            components[typeof(IBulkSaver)] = new SqlServerBulkSaver();
            components[typeof(IConnectionProviderBuilder)] = new SqlServerConnectionProviderBuilder();

            return components;
        }

        public T GetComponent<T>()
        {
            object component;
            bool exists = Components.TryGetValue(typeof(T), out component);
            if (exists && component != null)
                return (T)component;
            else
                return default(T);
        }
    }
}